/* Orbas:
 *     A open source CORBA Specification implementation from Huihoo.
 *
 * Copyright 2002-2003 Huihoo.org, Inc. All Right Reserved.
 *
 * This software is licensed under LGPL license.
 * See terms of license at gnu.org.
 *
 * For more information, visit:
 *
 * http://www.huihoo.org/orbas
 */

package org.huihoo.orbas.idl;

public abstract class VectorType extends TemplateTypeSpec {
	TypeSpec type_spec;

	public VectorType(int num) {
		super(num);
	}

	/**
	 * @return the TypeSpec for the sequence's element type
	 */

	public TypeSpec elementTypeSpec() {
		TypeSpec t = type_spec.typeSpec();

		/*
		 * if the element type is scoped name that refers to another type spec,
		 * we have to retrieve that. If that type spec is a base type or a
		 * string, we have to return it, otherwise we return the scoped type
		 * name.
		 */

		if (t instanceof ScopedName) {
			t = ((ScopedName) t).resolvedTypeSpec().typeSpec();
		}
		return t;
	}

	public void setTypeSpec(SimpleTypeSpec sts) {
		type_spec = sts;
	}

	/**
	 * @return this sequences Java type name, i.e., the element type with "[]"
	 *         appended.
	 */

	public String typeName() {
		String name;

		if (type_spec.typeSpec() instanceof ScopedName) {
			name = ((ScopedName) type_spec.typeSpec()).resolvedTypeSpec()
					.toString();
		} else {
			name = type_spec.toString();
		}

		return name + "[]";
	}

	boolean typedefd() {
		return typedefd;
	}

	public String printReadExpression(String streamname) {
		if (typedefd())
			return helperName() + ".read(" + streamname + ")";
		else
			return "*****";
	}

	protected String elementTypeExpression() {
		TypeSpec ts = type_spec.typeSpec();

		if (ts instanceof AliasTypeSpec) {
			return type_spec.full_name() + "Helper.type()";
		} else if (ts instanceof BaseType || ts instanceof TypeCodeTypeSpec
				|| ts instanceof ConstrTypeSpec || // for value types
				ts instanceof TemplateTypeSpec) {
			return ts.getTypeCodeExpression();
		} else {
			return ts.typeName() + "Helper.type()";
		}
	}

	public String elementTypeName() {
		TypeSpec ts = type_spec;
		if (ts instanceof ScopedName) {
			Environment.output(1, "elementTypeName is outer ScopedName");
			ts = ((ScopedName) type_spec.type_spec).resolvedTypeSpec();

			while (ts instanceof ScopedName || ts instanceof AliasTypeSpec) {
				if (ts instanceof ScopedName) {
					Environment.output(1, "elementTypeName is inner Alias");
					ts = ((ScopedName) ts).resolvedTypeSpec();
				}
				if (ts instanceof AliasTypeSpec) {
					Environment.output(1, "elementTypeName is inner Alias");
					ts = ((AliasTypeSpec) ts).originalType();
				}
			}
		}
		return ts.typeName();
	}

	public abstract String holderName();

	public abstract String helperName();

	public String toString() {
		return typeName();
	}

}
